import { reactive } from 'vue';
import { useDebounceFn } from '@vueuse/core';
import { TooltipState } from '../type';

// 常量定义
const TOOLTIP_CLASS = '.custom-tooltip';
const TOOLTIP_MARGIN = 10; // 提示框与元素的间距
const SHOW_DELAY = 300; // 显示延迟，避免快速移动时频繁触发

/**
 * 创建提示框模块
 */
export function tooltipModule() {
  // 提示框状态
  const tooltip = reactive<TooltipState>({
    visible: false,
    content: '',
    x: 0,
    y: 0
  });

  // 内部状态
  let tooltipElement: HTMLElement | null = null;

  /**
   * 计算提示框位置
   * @param target 目标元素
   * @returns 计算后的位置坐标
   */
  const calculateTooltipPosition = (target: HTMLElement): { x: number; y: number } => {
    // 尝试获取缓存的tooltipElement，如果没有则查找
    if (!tooltipElement) {
      tooltipElement = document.querySelector(TOOLTIP_CLASS) as HTMLElement;
    }

    // 如果仍未找到元素，返回默认位置
    if (!tooltipElement) {
      return { x: 0, y: 0 };
    }

    try {
      // 一次性获取所有需要的尺寸信息
      const { width: tooltipWidth, height: tooltipHeight } = tooltipElement.getBoundingClientRect();
      const { left: targetLeft, top: targetTop, width: targetWidth } = target.getBoundingClientRect();
      // 默认定位在单元格正上方并水平居中
      let x = targetLeft + targetWidth / 2 - tooltipWidth / 2;
      let y = targetTop - tooltipHeight - TOOLTIP_MARGIN;
      return { x, y };
    } catch (error) {
      console.warn('Error calculating tooltip position:', error);
      return { x: 0, y: 0 };
    }
  };

  // 创建防抖函数来显示提示框
  const debouncedShowTooltip = useDebounceFn((target: HTMLElement, contentStr: string) => {
    // 设置内容和可见性
    tooltip.content = contentStr;
    tooltip.visible = true;

    // 下一帧计算位置
    requestAnimationFrame(() => {
      const position = calculateTooltipPosition(target);
      tooltip.x = position.x;
      tooltip.y = position.y;
    });
  }, SHOW_DELAY);

  /**
   * 显示提示框
   * @param event 鼠标事件
   * @param content 提示内容
   */
  const showTooltip = (event: MouseEvent, content: string) => {
    // 验证参数并确保content是字符串类型
    if (!event || content === null || content === undefined) {
      return;
    }

    // 将content转换为字符串
    const contentStr = typeof content === 'string' ? content : String(content);

    // 检查内容是否为空
    if (contentStr.trim() === '') {
      return;
    }


    // 获取目标元素
    const target = event.target as HTMLElement;
    if (!target || target.scrollWidth <= target.clientWidth) {
      return;
    }

    // 使用防抖函数显示提示框
    debouncedShowTooltip(target, contentStr);
  };

  /**
   * 隐藏提示框
   */
  const hideTooltip = () => {
    // 重置状态（VueUse的useDebounceFn会在组件卸载时自动清理）
    tooltip.visible = false;
    tooltip.content = '';
    tooltip.x = 0;
    tooltip.y = 0;
  };

  /**
   * 清理提示框资源
   */
  const cleanupTooltip = () => {
    // 隐藏提示框
    hideTooltip();
    // 释放引用
    tooltipElement = null;
  };

  /**
   * 更新tooltip元素引用
   * @param element 提示框DOM元素
   */
  const updateTooltipElement = (element: HTMLElement | null) => {
    tooltipElement = element;
  };

  return {
    tooltip,
    showTooltip,
    hideTooltip,
    cleanupTooltip,
    updateTooltipElement
  };
}
